/*
 ============================================================================
 Name        : IODevice.c
 Author      : James McQueen, Corwyn Simpson, Craig Markham
 Version     :
 Date        : 05/14/2012
 Description : TCSS-422 Operating Systems Scheduler
 ============================================================================
 */

#include "IODevice.h"
#include <stdlib.h>
#include <time.h>

/* Private functions */

/* 
 */
void busyWait(CPU* cpu, int tick_count)
{
    int i = 0;
    for(; i < tick_count; i++)
    {
        nanosleep(&cpu->my_tick_time, NULL);
    }
}

/* Public functions */

IODevice* iodevice_init(CPU* cpu, int device_num, int interval, int is_random)
{
    IODevice* result = (IODevice*) malloc(sizeof(IODevice));
    iodevice_reinit(result, cpu, device_num, interval, is_random);
    return result;
}

void iodevice_reinit(IODevice* io, CPU* cpu, int device_num, int interval, int is_random)
{
    io->device_num = device_num;
    io->interval = interval;
    io->randomness_flag = is_random;
    io->cpu = cpu;
}

int iodevice_getDeviceNum(IODevice* io)
{
    return io->device_num;
}

int iodevice_getInterval(IODevice* io)
{
    return io->interval;
}

int iodevice_isRandom(IODevice* io)
{
    return io->randomness_flag;
}

int iodevice_isEnabled(IODevice* io)
{
    return io->is_enabled;
}

void iodevice_setEnabled(IODevice* io, int enable)
{
    io->is_enabled = enable;
}

void iodevice_toggleEnabled(IODevice* io)
{
    io->is_enabled = !io->is_enabled;
}

void* iodevice_run(void* io_pointer)
{
    IODevice* io = (IODevice*) io_pointer;
    while (1)
    {
        int tick_count = io->interval;
        if (io->randomness_flag == IO_RANDOM)
        { //tick_count is 0 to (2 * io->interval - 1), avg is still interval
            tick_count = (rand() % (2 * io->interval));
        }
        busyWait(io->cpu, tick_count);
        if (io->is_enabled)
        {
            cpu_interrupt(io->cpu, io->device_num);
        }
    }
    return (void*) 0; //successful return
}